//
//  PrizeClawVideoCallbackHandler.cpp
//  MyApp
//
//  Created by Don on 2017/8/22.
//
//
#ifdef __cplusplus
extern "C" {
#endif
    
    
#include "PrizeClawVideoHandler.hpp"

#include "glrenderer.h"

static PrizeClawVideoHandler* pcvInstance;
PrizeClawVideoHandler* PrizeClawVideoHandler::getInstance() {

    if (pcvInstance == NULL)
    {
        pcvInstance = new PrizeClawVideoHandler();
    }
    return pcvInstance;
}

PrizeClawVideoHandler::PrizeClawVideoHandler() {
//    videodecode_init();
}

PrizeClawVideoHandler::~PrizeClawVideoHandler() {
    LOGE("~PrizeClawVideoHandler free ..");
    if (videoDecoder) {
        
        videoDecoder->stop();
        
        delete videoDecoder;
        videoDecoder = NULL;
    }
    
    if (pcvInstance) {
        pcvInstance = NULL;
    }
    
}

void PrizeClawVideoHandler::starPrizeClawVideo(const char *rtmp_ip, const char *id, int channel, int width, int height) {
    printf("starPrizeClawVideo video screen size width:%d,height:%d\n",width,height);
    
    if (videoDecoder == NULL) {
        
        this->screenWidth = width;
        this->screenHeight = height;
        videoDecoder = new CVideoDecoder(onFrameAvailable, onFrameError, onFrameDidReady,onFrameStatus);
        LOGE("video decoder point %p",videoDecoder);
        videoDecoder->start(rtmp_ip, id, channel);
        LOGE("start affter video decoder point %p",videoDecoder);
    }
}
    
void PrizeClawVideoHandler::setCameraChannel(int channel) {
//    videodecode_toggle(channel);
    videoDecoder->swapChannel(channel);
}
    

// 注册回调函数的实现
void PrizeClawVideoHandler::registerFrameAvailableCallBackFunction(void * ref, FrameAvailableMessageHandler handler)
{
    this->ref = ref;
    this->frameAvailableHandler = handler;
    
}
void PrizeClawVideoHandler::registerFrameErrorCallBackFunction(void *ref, FrameErrorMessageHandler handler) {
    this->ref = ref;
    this->frameErrorHandler = handler;
}
    
void PrizeClawVideoHandler::registerFrameDidReadyCallBackFunction(void *ref, FrameDidReadyMessageHandler handler) {
    this->ref = ref;
    this->frameDidReadyHandler = handler;
}

void PrizeClawVideoHandler::registerFrameStatusCallBackFunction(void *ref, FrameStatusMessageHandler handler) {
    this->ref = ref;
    this->frameStatusHandler = handler;
}
#pragma mark - prize claw video callback
void PrizeClawVideoHandler::onFrameAvailable() {
//    printf("video frame available");
    if (pcvInstance && pcvInstance->ref) {

        uint8_t* frame = (uint8_t *)pcvInstance->videoDecoder->getDecodedFrame();//videodecode_getframe(pcvInstance->screenWidth,pcvInstance->screenHeight);
        if (pcvInstance->frameAvailableHandler != NULL && frame) {
            pcvInstance->frameAvailableHandler(pcvInstance->ref,frame);
        }
        pcvInstance->videoDecoder->freeDecodedFrame((char *)frame);
//        videodecode_releaseframe();
    }
    
    
}
void PrizeClawVideoHandler::onFrameDidReady(int videoWidth, int videoHeight) {
    if (pcvInstance && pcvInstance->ref) {
        if (pcvInstance->frameDidReadyHandler != NULL) {
            
            //根据视频实际长宽值，等比例计算实际渲染的高度
            pcvInstance->screenHeight = videoHeight*pcvInstance->screenWidth/videoWidth;
            pcvInstance->frameDidReadyHandler(pcvInstance->ref,videoWidth,videoHeight, pcvInstance->screenWidth, pcvInstance->screenHeight);
        }
    }
}

void PrizeClawVideoHandler::onFrameError(int error) {
    printf("video frame error ..");
    if (pcvInstance && pcvInstance->ref) {
        if (pcvInstance->frameErrorHandler != NULL) {
            pcvInstance->frameErrorHandler(pcvInstance->ref,error);
        }
    }
}
    
void PrizeClawVideoHandler::onFrameStatus(int bitrate, int max_bitrate, int recv_pkts, int decoded_pkts, int discard_pkts) {
    
    if (pcvInstance && pcvInstance->ref) {
        
        if (pcvInstance->frameStatusHandler != NULL) {
            pcvInstance->frameStatusHandler(pcvInstance->ref,bitrate,max_bitrate,recv_pkts,decoded_pkts,discard_pkts);
        }
    }
}
    
#ifdef __cplusplus
}
#endif

